package base;


import java.util.Arrays;
import java.util.Scanner;

public class Base64encode {

	private static char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".toCharArray();

	private static byte[] code =new byte[256];
	
	static{
		for(int i=0;i<256;i++){
			code[i]=-1;
		}
		for(int i='A';i<='Z';i++){
			code[i]= (byte)(i-'A');
		}
		for(int i='a';i<='z';i++){
			code[i]=(byte)(i-'a'+26);
		}
		for(int i='0';i<='9';i++){
			code[i]=(byte)(i-'0'+52);
		}
		code['+']=62;
		code['/']=63;
		
	}
	
	/* 编码  */
	public static String encode(byte[] data) {
		   char[] ch = new char[((data.length + 2) / 3) * 4];
		for (int i = 0, index = 0; i < data.length; i += 3, index += 4) {
			boolean fous = false;
			boolean thres = false;

			int value = (0xFF & (int) data[i]);
			value <<= 8;
			if ((i + 1) < data.length) {
				value |= (0xFF & (int) data[i + 1]);
				thres = true;
			}
			value <<= 8;
			if ((i + 2) < data.length) {
				value |= (0xFF & (int) data[i + 2]);
				fous = true;
			}

			ch[index + 3] = alphabet[fous ? (value & 0x3F) : 64];
			value >>= 6;
			ch[index + 2] = alphabet[thres ? (value & 0x3F) : 64];
			value >>= 6;
			ch[index + 1] = alphabet[value & 0x3F];
			value >>= 6;
			ch[index] = alphabet[value & 0x3F];

		}

		return new String(ch);
	}

	public static byte[] decode(String s) {
		char[] data =s.toCharArray();
		int len = ((data.length + 3) / 4) * 3;
		if (data.length > 0 && data[data.length - 1] == '=') {
			--len;
		}
		if (data.length > 0 && data[data.length - 2] == '=') {
			--len;
		}
		byte[] b = new byte[len];
		int index = 0;
		int count = 0;
		int cut = 0;
		for (int i = 0; i < data.length; i++) {
			int value = code[data[i] & 0xFF];
			if (value >= 0) {
				count <<= 6;
				cut += 6;
				count |= value;
				if (cut >= 8) {
					cut -= 8;
					b[index++] = (byte) ((count >> cut) & 0xFF);
				}
			}
		}
		if (index != b.length)
			throw new RuntimeException("错误的数据长度！");
		
		return b;
	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.println("输入需要加密的字符串：");
		String encodeInput = sc.nextLine();
		System.out.println("加密后的结果为：" + encode(encodeInput.getBytes()));

		System.out.println("输入需要解密的字符串：");
		String decodeInput = sc.nextLine();
		System.out.println("解密后的二进制结果为：" + Arrays.toString(decode(decodeInput)));
	}


}
